package felix.things.router.mqtt.server.store.subscribe;

import cn.hutool.core.util.StrUtil;
import felix.things.router.mqtt.server.common.subscribe.ISubscribeStoreService;
import felix.things.router.mqtt.server.common.subscribe.SubscribeStore;
import felix.things.router.mqtt.server.store.cache.SubscribeClientCache;
import felix.things.router.mqtt.server.store.cache.SubscribeNotWildcardCache;
import felix.things.router.mqtt.server.store.cache.SubscribeWildcardCache;
import felix.things.router.mqtt.server.store.utils.TopicUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * 订阅存储服务
 */
@Service
public class SubscribeStoreServiceImpl implements ISubscribeStoreService {

    @Autowired
    private SubscribeNotWildcardCache subscribeNotWildcardCache;

    @Autowired
    private SubscribeWildcardCache subscribeWildcardCache;

    @Autowired
    private SubscribeClientCache subscribeClientCache;

    @Override
    public void put(String topicFilter, SubscribeStore subscribeStore) {
        if (StrUtil.contains(topicFilter, '#') || StrUtil.contains(topicFilter, '+')) {
            subscribeWildcardCache.put(topicFilter, subscribeStore.getClientId(), subscribeStore);
        } else {
            subscribeNotWildcardCache.put(topicFilter, subscribeStore.getClientId(), subscribeStore);
        }
    }

    @Override
    public void remove(String topicFilter, String clientId) {
        if (StrUtil.contains(topicFilter, '#') || StrUtil.contains(topicFilter, '+')) {
            subscribeWildcardCache.remove(topicFilter, clientId);
        } else {
            subscribeNotWildcardCache.remove(topicFilter, clientId);
        }
    }

    @Override
    public void removeForClient(String clientId) {
        subscribeNotWildcardCache.removeForClient(clientId);
        subscribeWildcardCache.removeForClient(clientId);
        subscribeClientCache.delete(clientId);
    }

    @Override
    public List<SubscribeStore> search(String topic) {
        List<SubscribeStore> subscribeStores = new ArrayList<SubscribeStore>();
        List<SubscribeStore> list = subscribeNotWildcardCache.all(topic);
        if (list.size() > 0) {
            subscribeStores.addAll(list);
        }
        subscribeWildcardCache.all().forEach((topicFilter, map) -> {
            if (StrUtil.split(topic, '/').size() >= StrUtil.split(topicFilter, '/').size()) {
                String newTopicFilter = TopicUtils.topicConvert(topic, topicFilter);
                if (topicFilter.equals(newTopicFilter)) {
                    Collection<SubscribeStore> collection = map.values();
                    List<SubscribeStore> list2 = new ArrayList<SubscribeStore>(collection);
                    subscribeStores.addAll(list2);
                }
            }
        });
        return subscribeStores;
    }

}
